<template>
  <div class="ks-ht-chart-panel" v-bind:style="panelStyle">
    <div class="title">{{config.title}}</div>
    <div class="indicator">{{value.toFixed(0) + config.unitName}}<span class="indicator-sub-father"><span class="indicator-sub">{{rate.toFixed(0) + "%"}}</span></span></div>
    <div class="chart-area" ref="chart"></div>
  </div>
</template>

<script>
import * as d3 from "d3";
export default {
  data() {
    return {
      "value": Math.random() * 6000,
      "rate": Math.random() * 100,
      "panelStyle": {
        "width": this.config.width > 0 ? (this.config.width + "px") : "224px",
        "height": this.config.height > 0 ? (this.config.height + "px") : "150px"
      }
    }
  },
  props: {
    config : {
      type: Object,
      default: function() {
        return {
          "value": 5500,
          "rate": 56,
          "unitName": "t",
          "title": "标题",
          "colors": [
            "#00CF6F",    // Good 绿色
            "#FFC963",    // Normal 黄色
            "#E22425"     // Danger 红色
          ],
          "thresholds": [{
            "threshold": 2000,
            "alias": ""
          },{
            "threshold": 3000,
            "alias": ""
          }],
          "chart": {
            "top": 0,
            "left": 10,
            "bottom": 30,
            "right": 10
          }
        }
      }
    }
  },
  watch: {
    "value": function() {
      this.draw();
    },
    "rate": function() {
      this.draw();
    }
  },
  computed: {
    chartContentWidth() {
      let width = this.$refs.chart ? this.$refs.chart.clientWidth : 200;
      return width;
    },
    chartContentHeight() {
      let height = this.$refs.chart ? this.$refs.chart.clientHeight : 70;
      return height; 
    },
    /**
     * 渲染点（阈值、实际值和0）
     * 实际值和阈值决定坐标上的起止
     */
    points() {
      let points = [0];
      if(this.isValidNumber(this.value)) {
        points.push(this.value);
      }
      if(this.config.thresholds && this.config.thresholds.length > 0) {
        for(let i = 0; i < this.config.thresholds.length; i++) {
          let threshold = this.config.thresholds[i].threshold;
          if(this.isValidNumber(threshold)) {
            points.push(threshold);
          }
        }
      }
      // 排序
      points.sort(function(a,b){return a-b});
      // 去重
      let tempPoints = [];
      for(let i = 0; i < points.length; i++) {
        let point = points[i];
        if(tempPoints.indexOf(point) < 0) {
          tempPoints.push(point);
        }
      }
      return tempPoints;
    },
    range() {
      if(this.points.length == 0) {
        /**
         * 没阈值 没实际值
         */
        return {
          begin: -10,
          end: 110
        };
      } else if (this.points.length == 1) {
        /**
         * 只有一个渲染点
         */
        let point = this.points[0];
        if(point < 0) {
          return {
            begin: point * 11 / 10,
            end: point * -1 / 10
          }
        } else if (point == 0) {
          return {
            begin: -10,
            end: 110
          };
        } else {
          return {
            begin: point * 1 / 10,
            end: point * 11 / 10
          }
        }
      } else {
        let gap = this.points[this.points.length - 1] - this.points[0];
        return {
          begin: this.points[0] - 1 / 10 * gap,
          end: this.points[this.points.length - 1] + 1 / 10 * gap
        }
      }
    }
  },
  methods: {
    isValidNumber(x) {
      if(typeof x === 'string' && x !== "" && !isNaN(x)) {
        return true;
      }
      if(typeof x === 'number' && !isNaN(x)) {
        return true;
      }
      return false;
    },
    draw() {
      console.log(this.chartContentWidth, this.chartContentHeight, this.range, this.points);
      d3
        .select(this.$refs.chart)
        .selectAll("svg")
        .remove();
      let chart = d3
        .select(this.$refs.chart)
        .append('svg')
        .attr('width', this.chartContentWidth)
        .attr('height', this.chartContentHeight);

      chart
        .append("line")
        .attr("x1", this.config.chart.left)
        .attr("y1", this.chartContentHeight - this.config.chart.bottom)
        .attr("x2", this.chartContentWidth - this.config.chart.left)
        .attr("y2", this.chartContentHeight - this.config.chart.bottom)
        .attr("stroke","black")
        .attr("stroke-width",2);

      let len = this.chartContentWidth - this.config.chart.left - this.config.chart.right;
      
      for(let i = 0; i < this.config.thresholds.length; i++) {
        let threshold = this.config.thresholds[i].threshold;
        let alias = this.config.thresholds[i].alias ? this.config.thresholds[i].alias : (this.config.thresholds[i].threshold + this.config.unitName);

        let x = this.config.chart.left + len * (threshold - this.range.begin) / (this.range.end - this.range.begin);
        chart
          .append("line")
          .attr("x1", x)
          .attr("y1", this.chartContentHeight - this.config.chart.bottom)
          .attr("x2", x)
          .attr("y2", this.chartContentHeight - this.config.chart.bottom - 30)
          .attr("stroke","black")
          .attr("stroke-width",2);
        
        chart
          .append("text")
          .text(alias)
          .attr("x", x)
          .attr("y", this.chartContentHeight - this.config.chart.bottom + 12)
          .attr('text-anchor',"middle");
      }

      let zeroX = this.config.chart.left + len * (0 - this.range.begin) / (this.range.end - this.range.begin);

      let colorIndex = 0;

      for(;colorIndex < this.config.thresholds.length; colorIndex++) {
        if(this.value <= this.config.thresholds[colorIndex].threshold) {
          break;
        }
      }

      if(this.value < 0) {
        let width = len * (0 - this.value) / (this.range.end - this.range.begin);
        let height = 20;
        let x = zeroX - width;
        let y = this.chartContentHeight - this.config.chart.bottom - height;
        chart
          .append("rect")
          .attr("x", x)
          .attr("y", y)
          .attr("width", width)
          .attr("height", height)
          .attr("fill",this.config.colors[colorIndex]);
      } else {
        let width = len * this.value / (this.range.end - this.range.begin);
        let height = 20;
        let x = zeroX;
        let y = this.chartContentHeight - this.config.chart.bottom - height;
        chart
          .append("rect")
          .attr("x", x)
          .attr("y", y)
          .attr("width", width)
          .attr("height", height)
          .attr("fill", this.config.colors[colorIndex]);
      }
      // 零值位置
      chart
        .append("circle")
        .attr("cx", zeroX)
        .attr("cy", this.chartContentHeight - this.config.chart.bottom)
        .attr("r", 3)
        .attr("fill", "#FFFFFF")
        .attr("stroke","black")
        .attr("stroke-width",1);
    }
  },
  mounted() {
    this.draw();
  }
}
</script>

<style lang="less" scoped>
.ks-ht-chart-panel {
  box-sizing: border-box;
  margin: 20px;
  border: 2px solid #222;
  display: flex;
  flex-flow: column nowrap;
  align-items: center;

  .title {
    flex: none;
    font-size: 14px;
    font-weight: bold;
    margin-top: 4px;
  }

  .indicator {
    flex: none;
    font-size: 20px;
    font-weight: bold;
    position: relative;
    margin-top: 4px;

    .indicator-sub-father {
      visibility: hidden;
      position: relative;

      .indicator-sub {
        visibility: visible;
        position: absolute;
        left: 14px;
        bottom: 3px;
        font-size: 14px;
        font-weight: bold;
      }
    }
  }

  .chart-area {
    width: 100%;
    flex: auto;
  }
}
</style>